using Engine;
using Game;

namespace SCIENEW {
    /// <summary>
    /// 一些能在Draw方法里用到的实用方法
    /// </summary>
    public static class DrawingUtils {
        /// <summary>
        /// 依据给定参数，创建一个DrawBlockEnvironmentData
        /// </summary>
        /// <param name="subsystemTerrain"></param>
        /// <param name="position"></param>
        /// <returns></returns>
        public static DrawBlockEnvironmentData GetEnvironmentData(SubsystemTerrain subsystemTerrain, Vector3 position) => ModifyEnvironmentData(new DrawBlockEnvironmentData(), subsystemTerrain, position);

        /// <summary>
        /// 依据给定参数，调节DrawBlockEnvironmentData的内容
        /// </summary>
        /// <param name="environmentData"></param>
        /// <param name="subsystemTerrain"></param>
        /// <param name="position"></param>
        /// <returns></returns>
        public static DrawBlockEnvironmentData ModifyEnvironmentData(DrawBlockEnvironmentData environmentData, SubsystemTerrain subsystemTerrain, Vector3 position) {
            int x = Terrain.ToCell(position.X), y = Terrain.ToCell(position.Y), z = Terrain.ToCell(position.Z);
            environmentData.SubsystemTerrain = subsystemTerrain;
            TerrainChunk chunkAtCell = subsystemTerrain.Terrain.GetChunkAtCell(x, z);
            if (chunkAtCell != null
                && chunkAtCell.State >= TerrainChunkState.InvalidVertices1
                && y >= 0
                && y < 255) {
                environmentData.Humidity = subsystemTerrain.Terrain.GetSeasonalHumidity(x, z);
                environmentData.Temperature = subsystemTerrain.Terrain.GetSeasonalTemperature(x, z) + SubsystemWeather.GetTemperatureAdjustmentAtHeight(y);
                float f = MathUtils.Max(position.Y - y - 0.75f, 0f) / 0.25f;
                environmentData.Light = (int)MathUtils.Lerp(subsystemTerrain.Terrain.GetCellLightFast(x, y, z), subsystemTerrain.Terrain.GetCellLightFast(x, y + 1, z), f);
            }
            return environmentData;
        }

        /// <summary>
        /// 依据给定参数，调节DrawBlockEnvironmentData的内容\
        ///
        /// 传入方块坐标(Point3)，会自动将方块坐标移动至方块中心
        /// </summary>
        /// <param name="environmentData"></param>
        /// <param name="subsystemTerrain"></param>
        /// <param name="coordinates"></param>
        /// <returns></returns>
        public static DrawBlockEnvironmentData ModifyEnvironmentData(DrawBlockEnvironmentData environmentData, SubsystemTerrain subsystemTerrain, Point3 coordinates) => ModifyEnvironmentData(environmentData, subsystemTerrain, new Vector3(coordinates) + new Vector3(0.5f));

        public static bool IsVisible(SubsystemTerrain subsystemTerrain, Camera camera, Vector3 pos) {
            float range = subsystemTerrain.m_subsystemsky.VisibilityRange;
            if (Vector3.Distance(camera.ViewPosition, pos) < range - 16) {
                return true;
            }
            return false;
        }
    }
}